package ar.edu.utn.frba.dds.tp.code.vuelos;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import ar.edu.utn.frba.dds.tp.code.Asientos.AsientoDeVuelo;
import ar.edu.utn.frba.dds.tp.code.lugares.AbstractLugar;
import ar.edu.utn.frba.dds.tp.code.lugares.Lugar;
import ar.edu.utn.frba.dds.tp.code.ordenamientos.CriterioOrdenVuelos;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;


public class Busqueda {

	private AbstractLugar origen;
	private AbstractLugar destino;
	private Date fechaSalida;
	private List<Vuelo> vuelos;
	private List<Vuelo> vuelosFiltrados;
	private ArrayList<Predicate<AsientoDeVuelo>> filtros;
	private CriterioOrdenVuelos criteroParaOrdenar;

	
	private void setCriteroParaOrdenar(CriterioOrdenVuelos criteroParaOrdenar) {
		this.criteroParaOrdenar = criteroParaOrdenar;
	}

	private void setFiltros(ArrayList<Predicate<AsientoDeVuelo>> filtros) {
		this.filtros = filtros;
	}

	public Busqueda(Lugar origen, AbstractLugar lugar, Date fechaSalida) {
		
		this.origen = origen;
		this.destino = lugar;
		this.fechaSalida = fechaSalida;
		this.vuelos = new ArrayList<Vuelo>();
		this.vuelosFiltrados = new ArrayList<Vuelo>();
		
		BuscadorVuelos elBuscador = BuscadorVuelos.getInstance();
		elBuscador.buscar(this);
	}

	public List<Vuelo> getVuelos() {
		return this.vuelos;
	}
	
	public void addVuelos(List<Vuelo> vuelos) {
		for(Vuelo vuelo: vuelos){
			if(!this.vuelos.contains(vuelo))
				this.vuelos.add(vuelo);
		}
	}
	
	public void setVuelos(List<Vuelo> vuelos) {
		this.vuelos = vuelos;
	}

	public AbstractLugar getOrigen() {
		return origen;
	}

	public AbstractLugar getDestino() {
		return destino;
	}
	
	public Date getFechaSalida() {
		return fechaSalida;
	}
	
	public List<Vuelo> getVuelos(ArrayList<Predicate<AsientoDeVuelo>> filtros) {
		if(!filtros.isEmpty()) {
			List<Vuelo> vuelosFiltrados = new ArrayList<Vuelo>();
			for(Vuelo vuelo: this.getVuelos()) {
				Vuelo vueloFiltrado = vuelo.clone(); 
				for(Predicate<AsientoDeVuelo> filtro: filtros) {
					vueloFiltrado.setAsientos(Lists.newArrayList(Collections2.filter(vueloFiltrado.getAsientos(), filtro)));
				}
				if(!vueloFiltrado.getAsientos().isEmpty()) {
					vuelosFiltrados.add(vueloFiltrado);
				}
			}
			this.setFiltros(filtros);
			this.vuelosFiltrados  = vuelosFiltrados;
			}
		return this.vuelosFiltrados;
	}
	
	public List<Vuelo> getVuelos(CriterioOrdenVuelos criterio) {
		this.setCriteroParaOrdenar(criterio);
		return criterio.ordenarVuelos((ArrayList<Vuelo>) this.getVuelos());
	}
	
	public List<Vuelo> getVuelos(ArrayList<Predicate<AsientoDeVuelo>> filtros, CriterioOrdenVuelos criterio ){
		this.setCriteroParaOrdenar(criterio);
		return criterio.ordenarVuelos((ArrayList<Vuelo>) this.getVuelos(filtros));
		
	}

	public void removerVuelosSinAsientos() {
		for (Iterator<Vuelo> it = this.getVuelos().iterator(); it.hasNext(); ) {
			Vuelo vuelo = it.next();
			if(vuelo.getAsientos().isEmpty()) {
				it.remove();
			}
		}
	}
	
	public DataBusqueda guardarBusqueda(){
		DataBusqueda dbusqueda = new DataBusqueda(this.getOrigen(), this.getDestino(), this.getFechaSalida());
		dbusqueda.setCriteroParaOrdenar(this.criteroParaOrdenar);
		dbusqueda.setFiltros(this.filtros);
		dbusqueda.setVuelos(this.getVuelos());
		
		return dbusqueda;
	}
}

	

